/**   
 * Copyright 2011 COMERE Harold
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package etrl.core;

import com.googlecode.gwtgl.binding.WebGLRenderingContext;
import com.googlecode.gwtgl.binding.WebGLTexture;

import etrl.resources.Resources;
import etrl.vecmath.Matrix4f;
import etrl.vecmath.Vector3f;

/**
 * \class TextureLayer
 * \brief Class representing a texture layer applied on a geometry.
 * @author harold
 *
 */
public class TextureLayer
{
	/**
	 * \class InvalidTextureFilePathException
	 * \brief Exception class when the requested texture is not loaded.
	 * @author harold
	 *
	 */
	public class InvalidTextureFilePathException extends Exception {
		private static final long serialVersionUID = 1L; 
	}
	
	/**
	 * Current GL context.
	 */
	private WebGLRenderingContext _gl;
	
	/**
	 * GL Texture object.
	 */
	private WebGLTexture _texture;

	/**
	 * Transform data applied on texture coordinates
	 */
	private TransformData _transformData;

	/**
	 * \brief Initializes a texture layer from a requested texture.
	 * @param[in] filePath Requested texture file path.
	 * @throws InvalidTextureFilePathException
	 */
	public TextureLayer(String filePath) throws InvalidTextureFilePathException
	{
		_gl = Engine.getInstance().getGL();

		// Try to get the loaded texture resource associated to the given filepath
		_texture = Resources.instance().getTexture(filePath);
		
		// If there is no texture resource loaded for this filepath, error
		if(_texture == null)
			throw new InvalidTextureFilePathException();

		// Initialy no transformation is applied on texture coordinates, so let
		// the default transform data values
		_transformData = new TransformData();
	}

	/**
	 * \brief Activates the texture layer on the given texture unit.
	 * @param[in] unit Texture unit where to activate the layer.
	 */
	public void activate(int unit)
	{
		// TODO : TEXTURE0 + unit doesnt work in JAVA ;-(, find better way than
		// this switch.
		switch (unit)
		{
		case 0:
			_gl.activeTexture(WebGLRenderingContext.TEXTURE0);
			break;

		case 1:
			_gl.activeTexture(WebGLRenderingContext.TEXTURE1);
			break;

		case 2:
			_gl.activeTexture(WebGLRenderingContext.TEXTURE2);
			break;

		case 3:
			_gl.activeTexture(WebGLRenderingContext.TEXTURE3);
			break;

		case 4:
			_gl.activeTexture(WebGLRenderingContext.TEXTURE4);
			break;

		case 5:
			_gl.activeTexture(WebGLRenderingContext.TEXTURE5);
			break;

		case 6:
			_gl.activeTexture(WebGLRenderingContext.TEXTURE6);
			break;

		case 7:
			_gl.activeTexture(WebGLRenderingContext.TEXTURE7);
			break;
		}

		_gl.bindTexture(WebGLRenderingContext.TEXTURE_2D, _texture);
	}

	/**
	 * \brief Defines the scale applied to the texture coordinates on this layer.
	 * @param[in] scaleU Scale applied on U coordinate.
	 * @param[in] scaleV Scale applied on V coordinate.
	 */
	public void setScale(float scaleU, float scaleV)
	{
		_transformData.setScale(new Vector3f(scaleU, scaleV, 1.f));
	}

	/**
	 * \brief Computes the layer texture matrix.
	 * @return Texture matrix.
	 */
	public Matrix4f getTextureMatrix()
	{
		return _transformData.toMat4();
	}
}
